package com.bionic.banking.dao.classes;

import com.bionic.banking.core.entity.Address;
import com.bionic.banking.dao.IAddressDao;
import com.bionic.banking.dao.connection.DBQueryManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

public class AddressDaoImpl implements IAddressDao {
    
    protected final String SQL_SELECT = "SELECT * FROM " + getTableName();
    protected final String SQL_INSERT = "INSERT INTO " + getTableName()
            + "(postal_code, country, region, city, street,line1, line2)"
            + " VALUES(?,?,?,?,?,?,?)";
    protected final String SQL_UPDATE = "UPDATE " + getTableName()
            + " SET postal_code=?, country=?, region=?, city=?, street=?,line1=?, line2=? ";
    protected final String SQL_DELETE = "DELETE FROM " + getTableName();
    protected final String SQL_WHERE = " WHERE " + getKeyColumn() + "=?";
    protected static final int COLUMN_ADDRESSID = 1;
    protected static final int COLUMN_POSTALCODE = 2;
    protected static final int COLUMN_COUNTRY = 3;
    protected static final int COLUMN_REGION = 4;
    protected static final int COLUMN_CITY = 5;
    protected static final int COLUMN_STREET = 6;
    protected static final int COLUMN_LINE1 = 7;
    protected static final int COLUMN_LINE2 = 8;
    protected int maxRows;

    @Override
    public DBQueryManager<Address> getDBManager() {

        return new DBQueryManager<>(this);
    }

    @Override
    public String getTableName() {
        return "ADDRESS";
    }

    @Override
    public String getKeyColumn() {
        return "ADDRESS_ID";
    }

    @Override
    public Address populateDto(ResultSet rs) throws SQLException {
        Address dto = new Address();
        dto.setAddressId(rs.getInt(COLUMN_ADDRESSID));
        dto.setPostalCode(rs.getString(COLUMN_POSTALCODE));
        dto.setCountry(rs.getString(COLUMN_COUNTRY));
        dto.setRegion(rs.getString(COLUMN_REGION));
        dto.setCity(rs.getString(COLUMN_CITY));
        dto.setStreet(rs.getString(COLUMN_STREET));
        dto.setLine1(rs.getString(COLUMN_LINE1));
        dto.setLine2(rs.getString(COLUMN_LINE2));
        return dto;
    }

    public Integer create(Address address) throws SQLException {
        Object[] params = new Object[]{
            address.getPostalCode(),
            address.getCountry(),
            address.getRegion(),
            address.getCity(),
            address.getStreet(),
            address.getLine1(),
            address.getLine2()
        };
        Integer newAddressId = getDBManager().executeCreateQuery(SQL_INSERT, params);
        address.setAddressId(newAddressId); //update with new generated PK in DB 
        return newAddressId;
    }

    public boolean update(Address address) throws SQLException {
        final String query = SQL_UPDATE + SQL_WHERE;
        Object[] params = new Object[]{
            address.getPostalCode(),
            address.getCountry(),
            address.getRegion(),
            address.getCity(),
            address.getStreet(),
            address.getLine1(),
            address.getLine2(),
            address.getAddressId()
        };
        return getDBManager().executeSaveQuery(query, params);
    }

    @Override
    public void remove(int id) throws SQLException {
        final String query = SQL_DELETE + SQL_WHERE;
        getDBManager().executeRemoveQuery(query, id);
    }

    @Override
    public Address findById(int id) throws SQLException{
        String query = SQL_SELECT + SQL_WHERE;
        Object[] params = new Object[]{new Integer(id)};
        return getDBManager().executeSelectSingleQuery(query, params);
    }

    @Override
    public List<Address> findAll() throws SQLException {
        String query = SQL_SELECT;
        return getDBManager().executeSelectQuery(query, null);
    }

    @Override
    public void setMaxRows(int maxRows) {
        this.maxRows = maxRows;
    }

    @Override
    public int getMaxRows() {
        return maxRows;
    }
}
